package cn.gov.sdcj.accountancy.rule

import cn.gov.sdcj.accountancy.entity.VoucherList

/**
 * <p>Description: 会计规则管理对象
 * </p>
 *
 *
 * Created by laijie on 2015/3/27.
 */
class RuleManager {
    private final static RuleManager me = new RuleManager()
    private Map<String, Closure> rules = [:]

    public static RuleManager getRm() {
        return me
    }

    /**
     * 注册规则模板
     * @param name 注册名称
     * @param closure 规则模版
     */
    def static reg(String name, Closure rule) {
        me.rules.put(name, rule)
    }

    /**
     * 获取模板
     * @param name 模版的注册名称
     * @return 模版
     */
    Closure getRule(String name) {
        return rules.get(name)
    }

    public static boolean existsTemplate(String name) {
        return me.rules.containsKey(name);
    }

    /**
     * 将上下文（contexts)应用于规则
     * @param ruleName 规则
     * @param contexts 上下文对象
     * @return 凭证集合
     */
    public static VoucherList apply(String ruleName, Object... contexts) throws RuleException {
        def t = me.getRule(ruleName)
        if (null == t) {
            throw new RuleException("会计规则模板'" + ruleName +"'不存在！")
        }
        def builder = new RuleBuilder()
        contexts.each { context ->
            t = t.curry(context)
        }
        return builder.VoucherList(t)
    }

    /**
     * 将上下文（contexts 和 otherContext)应用于规则，其中 contexts 集合中的每个对象都会单独应用规则
     * @param ruleName 规则名称
     * @param contexts 上下文（Iterable 接口对象）
     * @param otherContext 其他上下文对象，可定义多个
     * @return 凭证集合
     */
    public static VoucherList apply(String ruleName, Iterable<Object> contexts, Object... otherContext)
            throws RuleException {
        VoucherList vouchers = new VoucherList()
        def t = me.getRule(ruleName)
        if (null == t) {
            throw new RuleException("会计规则模板'" + ruleName +"'不存在！")
        }
        def builder = new RuleBuilder()
        contexts.each { context ->
            def tm = t.curry(context)
            otherContext.each { other ->
                tm = tm.curry(other)
            }
            def v = builder.VoucherList(tm)
            vouchers = vouchers + v
        }
        return vouchers
    }
}
